use std::{ops::{Deref, DerefMut}, sync::Arc};
use mf_core::{ForgeResult, extension::Extension, runtime::builder::AnyRuntime, types::Extensions, ForgeError};
use mf_file::{DocumentWriter, SegmentType};
use mf_state::error::error;
use price_common::bootstrap::BootstrapArtifacts;
use price_rules::rules_engine::RulesEngine;

/// 预算运行时
///
/// BudgetRuntime 是预算系统的核心运行时组件，负责管理预算计算过程中的所有操作。
/// 它不仅仅是一个"编辑器"，而是整个预算系统的执行引擎。
///
/// # 功能概述
/// - 封装底层 ModuForge 运行时，提供高级预算计算接口
/// - 管理和访问系统中的各类资源，如规则引擎、数据源等
/// - 通过 Deref/DerefMut 实现对底层运行时的透明访问
/// - 直接从 Bootstrap 产物创建，无需中间配置层
///
/// # 设计理念
/// - 使用 `AnyRuntime` 枚举避免动态分发开销
/// - 完全集成 Bootstrap 机制，消除冗余配置
/// - **Bootstrap 产物包含所有配置**：业务配置 + 运行时配置 + 性能配置
/// - 一行代码创建运行时，无需手动配置
///
/// # 创建方式
/// 推荐使用 `from_bootstrap()` 方法，它直接从 Bootstrap 产物创建运行时：
///
/// ```rust
/// use price_common::bootstrap::{BootstrapRegistry, ProjectProfile, ProjectPhase};
/// use price_budget_core::runtime::BudgetRuntime;
///
/// // 1. 执行 bootstrap（包含所有配置）
/// let artifacts = loader.bootstrap(profile).await?;
///
/// // 2. 直接创建运行时（一行代码！Bootstrap 包含所有配置）
/// let runtime = BudgetRuntime::from_bootstrap(artifacts).await?;
/// ```
pub struct BudgetRuntime {
    /// 内部运行时实例，处理底层操作
    ///
    /// 负责状态管理、撤销/重做操作以及资源跟踪等基础功能
    /// 使用 AnyRuntime 枚举避免动态分发开销，提供更好的性能
    runtime: AnyRuntime,

    /// Bootstrap 产物（方案 A：包含所有配置）
    ///
    /// 保存 Bootstrap 阶段产生的所有配置和资源，包括：
    /// - 项目配置（ProjectProfile）
    /// - 业务配置（规则加载器、扩展、元数据、数据源）
    /// - 运行时配置（RuntimeOptions: content, history_limit, event_handlers）
    /// - 性能配置（ForgeConfig: 并发数、队列大小、监控等）
    artifacts: BootstrapArtifacts,
}

unsafe impl Send for BudgetRuntime {}
unsafe impl Sync for BudgetRuntime {}

impl BudgetRuntime {
    /// 从 Bootstrap 产物创建预算运行时（方案 A 实现）
    ///
    /// **这是推荐的创建方式！** Bootstrap 产物包含所有必要的配置：
    /// - 业务配置（扩展、规则、数据源、元数据）
    /// - 运行时配置（RuntimeOptions: content, history_limit, event_handlers）
    /// - 性能配置（ForgeConfig: 并发数、队列大小、监控等）
    ///
    /// 无需手动配置，一行代码即可创建完整的运行时！
    ///
    /// # 参数
    /// * `artifacts` - Bootstrap 阶段产生的产物集合（包含所有配置）
    ///
    /// # 返回
    /// * `ForgeResult<Self>` - 成功返回运行时实例，失败返回错误
    ///
    /// # 示例
    /// ```rust
    /// use price_common::bootstrap::{BootstrapRegistry, ProjectProfile, ProjectPhase};
    /// use price_budget_core::runtime::BudgetRuntime;
    ///
    /// // 1. 在 Bootstrap 阶段注册所有配置
    /// let mut registry = BootstrapRegistry::new();
    /// registry.register_schema(selector, schema_provider);
    /// registry.register_rule(selector, rule_provider);
    /// registry.register_runtime_config(selector, runtime_config_provider);  // 新增
    /// registry.register_forge_config(selector, forge_config_provider);      // 新增
    ///
    /// // 2. 执行 bootstrap
    /// let loader = registry.build_loader(&profile);
    /// let artifacts = loader.bootstrap(profile).await?;
    ///
    /// // 3. 一行代码创建运行时（所有配置都在 artifacts 中）
    /// let runtime = BudgetRuntime::from_bootstrap(artifacts).await?;
    /// ```
    pub async fn from_bootstrap(mut artifacts: BootstrapArtifacts) -> ForgeResult<Self> {
        // 从 artifacts 中提取规则加载器
        let rule_loader = artifacts.rule_loader();

        // 创建规则引擎扩展
        let mut extension = Extension::default();
        extension.add_op_fn(Arc::new(move |op_state| {
            op_state.put(RulesEngine::new(rule_loader.clone()));
            Ok(())
        }));

        // 将规则引擎扩展添加到 artifacts 中
        artifacts.add_extension(Extensions::E(extension));

        // 方案 A 的核心：直接使用 artifacts.build_runtime()
        // Bootstrap 已经包含了所有配置：
        // - 业务扩展（schema, plugins）
        // - 规则引擎扩展（刚刚添加）
        // - RuntimeOptions（content, history_limit, event_handlers）
        // - ForgeConfig（并发数、队列大小、监控等）
        let runtime = artifacts.build_runtime().await?;

        Ok(Self { runtime, artifacts })
    }

    /// 获取 Bootstrap 产物的引用
    ///
    /// 可以访问项目配置、元数据、数据源等信息
    pub fn artifacts(&self) -> &BootstrapArtifacts {
        &self.artifacts
    }

    /// 获取规则加载器
    ///
    /// 这是一个便捷方法，等价于 `self.artifacts().rule_loader()`
    pub fn rule_loader(&self) -> Arc<dyn price_rules::loader::RulesLoaderExt> {
        self.artifacts.rule_loader()
    }

    /// 获取规则引擎实例
    ///
    /// 返回当前运行时使用的规则引擎，用于执行预算规则和业务逻辑
    ///
    /// # 返回
    /// * `ForgeResult<Arc<RulesEngine>>` - 成功返回规则引擎的Arc引用，失败返回错误
    ///
    /// # 错误
    /// 如果规则引擎未初始化或获取失败，将返回相应的错误
    pub async fn get_rules_engine(&self) -> ForgeResult<Arc<RulesEngine>> {
        let state = self.runtime.get_state().await?;
        let resource_manager = state.resource_manager();
        resource_manager.get::<RulesEngine>().ok_or_else(|| mf_core::ForgeError::Internal {
            message: "规则引擎未初始化".to_string(),
            location: Some("BudgetRuntime::get_rules_engine".to_string()),
        })
    }

    ///导出文件
    pub async fn export(&self,path: String)->ForgeResult<()>{
        let state =self.get_state().await?;
        let _ =tokio::spawn(async move {
            let state =state;
            let mut w  = DocumentWriter::begin(path).map_err(|e|ForgeError::Internal { message: e.to_string(), location: None })?;
            //写入插件内容
            for plugin in state.plugins().await {
                if let Some(state_field) = &plugin.spec.state_field {
                    if let Some(value) = state.get_field(&plugin.key) {
                        if let Some(bytes) = state_field.serialize_erased(value) {
                            let _=w.add_segment(SegmentType(plugin.key.clone()),&bytes);
                        }
                    };
                }
            }
            let doc =state.doc();
            let tree =doc.get_inner();
            for ns  in tree.nodes.iter() {
               if ns.keys().len()>0{
                  let json = serde_json::to_string(ns).map_err(|e| {
                       error::serialize_error(format!("node pool 序列化失败: {e}"))
                   })?;
                   let bytes =json.as_bytes().to_vec();
                   let _ = w.add_segment(SegmentType("doc".to_string()),&bytes);
               }
            }
            w.finalize().map_err(|e|ForgeError::Internal { message: e.to_string(), location: None })?;
            Ok::<(), ForgeError>(())
        });
        Ok(())
    }
}

/// 实现 Deref trait，允许 BudgetRuntime 透明地解引用为 AnyRuntime
///
/// 这使得可以直接在 BudgetRuntime 实例上调用 AnyRuntime 的方法
/// 例如，`runtime.undo()` 将直接调用底层运行时的 undo 方法
///
/// # 使用示例
/// ```
/// let runtime = BudgetRuntime::from_bootstrap(artifacts).await?;
///
/// // 直接调用运行时的方法
/// runtime.undo().await?;
/// runtime.redo().await?;
/// ```
impl Deref for BudgetRuntime {
    type Target = AnyRuntime;

    fn deref(&self) -> &Self::Target {
        &self.runtime
    }
}

/// 实现 DerefMut trait，允许对 BudgetRuntime 内部的运行时进行可变访问
///
/// 这使得可以在需要可变引用的场景下直接使用 BudgetRuntime 调用运行时的方法
/// 例如，`runtime.dispatch()` 将直接调用底层运行时的相应方法
impl DerefMut for BudgetRuntime {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.runtime
    }
}
